import httplib, urllib
import time
import gaccount
  
class GoogleCalendarAPI(gaccount.GoogleAccountAPI):
  def __init__(self, email=None, password=None, use_json=True, source="CMU-GoogleCalendarAPI-1"):
    gaccount.GoogleAccountAPI.__init__(self, email, password, source)
    self._resp = None
    self._error = None
    self.use_json = use_json
    
  def _get_calendars(self, url):  
    root = self.request_gdata(url, self.use_json)
    clist = None
    if self.use_json:
      clist = CalendarList(self, root["feed"]["id"]["$t"], root["feed"]["title"]["$t"])
      for entry in root["feed"]["entry"]:
        clist.add_calendar(Calendar(self, entry))
    else:
      clist = CalendarList(self, root.childnodes["id"][0].content, root.childnodes["title"][0].content)
      for entry in root.childnodes["entry"]:
        clist.add_calendar(Calendar(self, entry))
    return clist
    
  def get_own_calendars(self):
    return self._get_calendars("http://www.google.com/calendar/feeds/default/owncalendars/full")
  
  def get_all_calendars(self):
    return self._get_calendars("http://www.google.com/calendar/feeds/default/allcalendars/full")  
  
#  def get_all_events(self, calendars, start_time=None, end_time=None):
#    query = ""
#    if start_time != None and end_time != None:
#      query = "?" + urllib.urlencode({'start-min':start_time, 'start-max':end_time})      
#    batch_req = BatchRequest()
#    for cal in calendars:
#      batch_req.add(QueryBatch(cal.get_content() + query))
#    root = self.post_gdata("http://www.google.com/calendar/feeds/default/allcalendars/full/batch", batch_req.to_s(), True)
#    return root
    
class Event:
  def __init__(self, entry, use_json=True):
    self.start_time = None
    self.end_time = None
    self.sequence = None
    self.recurrence = None
    self.content = None
    self.where = None
    self.updated = None
    if use_json:
      self._id = entry["id"]["$t"]
      self.title = entry["title"]["$t"]
      self.updated = entry["updated"]["$t"]
      if entry["content"].has_key("$t"):
        self.content = entry["content"]["$t"]
      if entry.has_key("gd$when"):
        self.start_time = gaccount.to_localtime(entry["gd$when"][0]["startTime"])
        self.end_time = gaccount.to_localtime(entry["gd$when"][0]["endTime"])
      if entry.has_key("gCal$sequence"):
        self.sequence = entry["gCal$sequence"]["value"]
      if entry.has_key("gd$recurrance"):
        self.recurrence = entry["gd$recurrance"]["$t"]
      if entry.has_key("gd$where") and len(entry["gd$where"])>0 and entry["gd$where"][0].has_key("valueString"):
        self.where = entry["gd$where"][0]["valueString"]        
    else :
      self._id = entry.childnodes["id"][0].content
      self.title = entry.childnodes["title"][0].content
      self.updated = entry.childnodes["updated"][0].content
      self.content = entry.childnodes["content"][0].content
      if entry.childnodes.has_key("gd:when"):
        self.start_time = entry.childnodes["gd:when"][0].properties["startTime"]
        self.end_time = entry.childnodes["gd:when"][0].properties["endTime"]
      if entry.childnodes.has_key("gCal:sequence"):
        self.sequence = entry.childnodes["gCal:sequence"][0].properties["value"]
      if entry.childnodes.has_key("gd:recurrance"):
        self.recurrence = entry.childnodes["gd:recurrance"][0].content
      if entry.childnodes.has_key("gd:where"):
        self.where = entry.childnodes["gd:where"][0].properties["valueString"]
    
class Calendar:
  def __init__(self, gcal, entry):
    self._gcal = gcal
    if gcal.use_json:
      self._id = entry["id"]["$t"]
      self.title = entry["title"]["$t"]
      self._content = entry["content"]["src"]
      self._access_level = entry["gCal$accesslevel"]["value"]
    else:
      self._id = entry.childnodes["id"][0].content
      self.title = entry.childnodes["title"][0].content
      self._content = entry.childnodes["content"][0].properties["src"]
      self._sequence = entry.childnodes["gCal:accesslevel"][0].properties["value"]
    
  def get_id(self):
    return self._id
  
  def get_content(self):
    return self._content
  
  def access_level(self):
    return self._access_level
  
  def get_events(self, start_time=None, end_time=None):
    query = ""
    if start_time != None and end_time != None:
      query = "?" + urllib.urlencode({'start-min':start_time, 'start-max':end_time, 'singleevents':'true'})   
    root = self._gcal.request_gdata(self._content + query, self._gcal.use_json)
    events = []
    if self._gcal.use_json:
      if root["feed"].has_key("entry"):
        for entry in root["feed"]["entry"]:
          events.append(Event(entry, True))
    else:
      if root.childnodes.has_key("entry"):
        for entry in root.childnodes["entry"]:
          events.append(Event(entry, False))
    return events
    
class CalendarList:
  def __init__(self, gcal, id, title=''):
    self._gcal = gcal
    self._id = id
    self._title = title
    self._calendars = []  
    
  def get_id(self):
    return self._id
  
  def get_title(self):
    return self._title
         
  def add_calendar(self, cal):
    self._calendars.append(cal)
    
  def get_calendars(self):
    return self._calendars
  
class Batch:
  def __init__(self, type):
    self.type = type
    self.id = None
    
  def _to_s_header(self):
    return "<entry><batch:id>%d</batch:id><batch:operation type='%s'/>" % (self.id, self.type)

  def _to_s_footer(self):
    return "</entry>"
    
  def to_s(self):
    return self._to_s_header() + self._to_s_footer()
    
class QueryBatch(Batch):
  def __init__(self, url):
    Batch.__init__(self, "query")
    self._url = url;
  
  def to_s(self):
    xml = self._to_s_header()
    xml = xml + "<id>%s</id>" % self._url
    xml = xml + "<category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/g/2005#event'/>"
    xml += self._to_s_footer()
    return xml    
  
class BatchRequest:
  def __init__(self):
    self._xml = "<feed xmlns='http://www.w3.org/2005/Atom' xmlns:batch='http://schemas.google.com/gdata/batch' xmlns:gCal='http://schemas.google.com/gCal/2005'>"
    self._xml = self._xml + "<category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/g/2005#event' />"
    self._batch_list = []

  def add(self, batch):
    self._batch_list.append(batch)
    batch.id = len(self._batch_list)

  def to_s(self):
    for batch in self._batch_list:
      self._xml = self._xml + batch.to_s()
    self._xml = self._xml + "</feed>"
    return self._xml
    
def main():
  start = time.time()
  print "GooglaCalendarAPI Test: start at %d sec" % start  
  
  gcal = GoogleCalendarAPI("tony.lin@west.cmu.edu", "")
  print "Auth=%s" % gcal.get_auth()
  if gcal.get_auth() == None:
    print "Error=%s" % gcal.get_error()
#  cals = gcal.get_own_calendars()
  cals = gcal.get_all_calendars()
  print cals
  if cals == None:
    print "Error=%s" % gcal.get_error()
  else:
    now = time.gmtime()
    week = time.gmtime(time.time()+7*24*60*60)
    for cal in cals.get_calendars():
  #    log cal.get_content()
      for e in cal.get_events(time.strftime("%Y-%m-%d", now),time.strftime("%Y-%m-%d", week)):
        print("%s=%s-%s"%(e.title, e.start_time, e.end_time))
    if cals == None:
      print ("Error=%s" % gcal.get_error())    
  end = time.time()
  print "GoogleCalendarAPI Test pass: end at %(end) sec, total=%(total) seconds" % {"end":end, "total":(end - start)}

 
if __name__ == "__main__":
  main()
  